home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
Bitmap.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-26
|
5KB
|
303 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "Bitmap.h"
#include "Class.h"
#include "DevBitmap.h"
#include "Error.h"
#include "Storage.h"
#include "WindowSystem.h"
#include "String.h"
#include "OrdColl.h"
#include "Data.h"
#include "STREAMFILTERS/HexFilter.h"
#include "STREAMFILTERS/LZWFilter.h"
#include "STREAMFILTERS/RLEFilter.h"
#include "STREAMFILTERS/A85Filter.h"
//---- SmartBitmap -------------------------------------------------------------
Bitmap *SmartBitmap::MakeBitmap()
{
if (name) {
FileData *fd;
if (name[0] == '/')
fd= new FileData((char*)name);
else {
fd= new FileData(form("/%s/src/images/%s", gEtDir, name));
}
bm= (Bitmap*) fd->AsObject(Meta(Bitmap));
delete fd;
} else if (bits) {
bm= new Bitmap(size, bits);
} else
fprintf(stderr, "SmartBitmap::MakeBitmap(): oops\n");
return bm;
}
//---- Bitmap ------------------------------------------------------------------
NewMetaImpl0(Bitmap,Ink);
Bitmap::Bitmap(Point sz, u_short depth)
{
WindowSystem::WSInit();
dbm= gWindowSystem->MakeDevBitmap(sz, 0, depth);
mask= 0;
if (dbm)
dbm->Ref();
}
Bitmap::Bitmap(Point sz, u_short *im, u_short depth)
{
WindowSystem::WSInit();
dbm= gWindowSystem->MakeDevBitmap(sz, im, depth);
mask= 0;
if (dbm)
dbm->Ref();
}
Bitmap::Bitmap(int sz, u_short *im, u_short depth)
{
WindowSystem::WSInit();
dbm= gWindowSystem->MakeDevBitmap(sz, im, depth);
mask= 0;
if (dbm)
dbm->Ref();
}
Bitmap::Bitmap(DevBitmap *d)
{
WindowSystem::WSInit();
dbm= d;
mask= 0;
if (dbm)
dbm->Ref();
}
Bitmap::Bitmap(const char*)
{
WindowSystem::WSInit();
fprintf(stderr, "Bitmap::Bitmap((char*): not yet implemented\n");
dbm= mask= 0;
if (dbm)
dbm->Ref();
}
Bitmap::~Bitmap()
{
if (dbm) {
dbm->Unref();
dbm= 0;
}
if (mask) {
mask->Unref();
mask= 0;
}
}
Point Bitmap::Size()
{
return dbm->Size();
}
int Bitmap::ShortsPerLine()
{
return ((dbm->Size().x-1)/16+1)*dbm->Depth();
}
int Bitmap::BytesPerLine()
{
return dbm->BytesPerLine();
}
int Bitmap::GetDepth()
{
return dbm->Depth();
}
void Bitmap::SetDevBitmap(DevBitmap *d)
{
if (dbm) {
dbm->Unref();
dbm= 0;
}
if (d) {
dbm= d;
dbm->Ref();
}
Changed();
}
void Bitmap::SetDevMask(DevBitmap *m)
{
if (mask) {
mask->Unref();
mask= 0;
}
if (m) {
mask= m;
mask->Ref();
}
Changed();
}
void Bitmap::Fill(u_int val)
{
Point sz= Size();
for (int x= 0; x < sz.x; x++)
for (int y= 0; y < sz.y; y++)
dbm->SetPixel(x, y, val);
Changed();
}
void Bitmap::seedfill(int x, int y, u_int seed, u_int val)
{
if (GetPixel(x, y) == seed) {
dbm->SetPixel(x, y, val);
seedfill(x-1, y, seed, val);
seedfill(x+1, y, seed, val);
seedfill(x, y+1, seed, val);
seedfill(x, y-1, seed, val);
}
}
void Bitmap::SeedFill(Point where, u_int val)
{
u_int oldval= GetPixel(where.x, where.y);
if (val == oldval) // prevent endless recursion
seedfill(where.x, where.y, oldval, oldval= (val+1) % 256);
seedfill(where.x, where.y, oldval, val);
Changed();
}
void Bitmap::SetInk(Port *port)
{
port->DevSetPattern(dbm);
}
void Bitmap::SetPixel(u_int x, u_int y, u_int val)
{
if (x >= 0 && x < dbm->Size().x && y >= 0 && y < dbm->Size().y) {
dbm->SetPixel(x, y, val);
Rectangle r(x, y, 1, 1);
Send(cIdNone, cPartPixelChanged, &r);
}
}
u_int Bitmap::GetPixel(u_int x, u_int y)
{
if (x >= 0 && x < dbm->Size().x && y >= 0 && y < dbm->Size().y)
return dbm->GetPixel(x, y);
return 0;
}
Object *Bitmap::deepclone()
{
if (IsA() == Meta(Bitmap)) {
Bitmap *bm= new Bitmap(Size(), GetDepth());
bm->dbm= dbm->DeepClone();
return bm;
}
return 0;
}
OStream &Bitmap::PrintOn(OStream &s)
{
register int x, y;
int enc;
Point size= Size();
int cmsize= dbm->GetColormapSize();
int bpl= BytesPerLine();
Object::PrintOn(s);
enc= 0;
if (Bytes() > 100) {
if (GetDepth() > 1)
enc= 3;
else
enc= 2;
}
s << size SP << GetDepth() SP << enc SP << cmsize NL;
if (cmsize > 0)
s << *dbm->cmap NL;
if (enc == 0) {
s.Push(new HexEncoder);
} else if (enc == 1) {
s.Push(new HexEncoder);
s.Push(new RLEEncoder);
} else if (enc == 2) {
s.Push(new A85Encoder);
s.Push(new RLEEncoder);
} else if (enc == 3) {
s.Push(new A85Encoder);
s.Push(new LZWEncoder);
}
register StreamBuf *sb= s.getsbuf();
for (y= 0; y < size.y; y++)
for (x= 0; x < bpl; x++) {
int c= (int) dbm->GetByte(x, y);
sb->sputc(c);
}
if (enc > 0)
s.Pop();
s.Pop();
return s;
}
IStream &Bitmap::ReadFrom(IStream &s)
{
int decd, depth, cmsize;
Point size;
if (dbm) {
dbm->Unref();
dbm= 0;
}
Object::ReadFrom(s);
s >> size >> depth >> decd >> cmsize;
dbm= gWindowSystem->MakeDevBitmap(size, 0, depth);
if (dbm)
dbm->Ref();
if (cmsize > 0) {
dbm->SetColormapSize(cmsize);
s >> *dbm->cmap;
}
if (decd == 0) {
s.Push(new HexDecoder);
} else if (decd == 1) {
s.Push(new HexDecoder);
s.Push(new RLEDecoder(TRUE));
} else if (decd == 2) {
s.Push(new A85Decoder);
s.Push(new RLEDecoder(FALSE));
} else if (decd == 3) {
s.Push(new A85Decoder);
s.Push(new LZWDecoder);
}
dbm->ReadData(s, depth, 1);
if (decd > 0)
s.Pop();
s.Pop();
return s;
}